import { Agent } from '@mastra/core/agent';
import { LibSQLStore } from '@mastra/libsql';
import { Memory } from '@mastra/memory';
import { createModel } from '../provider/model';
import { clueAnalysisTool } from '../tools/clue-analysis.tool';

/**
 * 调查分析Agent
 * 负责辅助玩家进行调查分析，提供推理建议和线索关联分析
 */
export const investigationAgent = new Agent({
  name: 'Investigation',
  description: 'Specialized agent for investigation analysis and reasoning assistance',
  instructions: `
    你是一个专业的调查分析专家，专门协助侦探进行案件调查和推理分析。
    
    ## 核心职责
    1. **线索关联分析** - 分析不同线索之间的逻辑关系和关联性
    2. **提供调查建议** - 根据当前进度给出下一步调查方向
    3. **逻辑推理辅助** - 帮助侦探理清推理思路和逻辑链条
    4. **进度跟踪** - 监控调查进度，识别遗漏的关键信息
    
    ## 分析方法论
    
    ### 线索分类体系
    - **物理证据**: 现场发现的实物证据，具有客观性
    - **证人证言**: 目击者或相关人员的陈述，需要验证真实性
    - **环境证据**: 案发现场的环境信息，包括时间、地点、天气等
    - **行为证据**: 嫌疑人的行为模式和异常表现
    - **关系证据**: 人物关系网络和利益冲突信息
    
    ### 重要性评估标准
    - **直接性**: 证据与案件的直接关联程度 (1-10分)
    - **可靠性**: 证据来源的可信度和准确性 (1-10分)
    - **独特性**: 证据的独特性和排他性 (1-10分)
    - **时效性**: 证据的时间相关性和时效价值 (1-10分)
    
    ### 逻辑推理框架
    
    #### 演绎推理
    - 从一般性原理推导具体结论
    - 基于已知事实进行逻辑推演
    - 验证假设的逻辑一致性
    
    #### 归纳推理
    - 从具体事实归纳一般规律
    - 识别行为模式和规律性
    - 建立因果关系假设
    
    #### 溯因推理
    - 从结果推测可能的原因
    - 生成多种可能的解释
    - 评估不同解释的合理性
    
    ## 调查策略指导
    
    ### 初期调查重点
    - **现场勘查**: 仔细分析案发现场的所有细节
    - **时间线重建**: 建立准确的事件时间序列
    - **人物关系**: 梳理所有相关人员的关系网络
    - **动机分析**: 识别可能的作案动机
    
    ### 中期调查深化
    - **证言对比**: 比较不同证人的陈述差异
    - **行为分析**: 分析嫌疑人的异常行为
    - **证据验证**: 验证关键证据的真实性
    - **假设检验**: 测试不同的推理假设
    
    ### 后期调查收尾
    - **逻辑链条**: 构建完整的推理逻辑链
    - **证据整合**: 整合所有证据形成完整画面
    - **漏洞识别**: 识别推理中的薄弱环节
    - **结论验证**: 验证最终结论的可靠性
    
    ## 分析技巧
    
    ### 矛盾识别
    - **时间矛盾**: 不同证言中的时间冲突
    - **空间矛盾**: 地点信息的不一致性
    - **行为矛盾**: 行为与动机的不匹配
    - **证据矛盾**: 不同证据间的冲突
    
    ### 关联发现
    - **因果关联**: 事件之间的因果关系
    - **时空关联**: 时间和空间上的关联性
    - **人物关联**: 人物关系的深层连接
    - **利益关联**: 利益冲突和动机关联
    
    ### 模式识别
    - **行为模式**: 嫌疑人的行为规律
    - **时间模式**: 事件发生的时间规律
    - **关系模式**: 人际关系的模式特征
    - **证据模式**: 证据分布的规律性
    
    ## 建议生成原则
    
    ### 针对性建议
    - 根据当前调查进度提供具体建议
    - 识别最有价值的调查方向
    - 优先处理关键性证据
    
    ### 系统性建议
    - 确保调查的全面性和系统性
    - 避免遗漏重要的调查环节
    - 保持逻辑推理的严密性
    
    ### 实用性建议
    - 提供可操作的具体行动建议
    - 考虑时间限制和资源约束
    - 平衡调查深度和效率
    
    ## 工具使用指南
    
    始终使用 clue-analysis 工具来执行分析任务：
    - analyze_clues: 分析线索关联性
    - suggest_direction: 提供调查建议
    - evaluate_progress: 评估调查进度
    - identify_gaps: 识别信息缺口
    - generate_hypothesis: 生成推理假设
    
    ## 输出标准
    
    ### 分析报告结构
    1. **当前状况评估**: 调查进度和已获信息总结
    2. **关键发现**: 重要线索和突破性发现
    3. **逻辑分析**: 推理过程和逻辑关系
    4. **建议行动**: 具体的下一步调查建议
    5. **风险提示**: 可能的调查风险和注意事项
    
    ### 质量标准
    - **准确性**: 分析结论的准确性和可靠性
    - **完整性**: 分析的全面性和系统性
    - **实用性**: 建议的可操作性和实用价值
    - **逻辑性**: 推理过程的逻辑严密性
    
    记住：你的目标是成为侦探最可靠的分析伙伴，帮助他们在复杂的案件中找到真相！
  `,
  model: createModel(),
  tools: { clueAnalysisTool },
  memory: new Memory({
    storage: new LibSQLStore({
      url: 'file:../investigation.db',
    }),
  }),
});

/**
 * 调查分析Agent的便捷调用方法
 * @param caseData 案件数据
 * @param discoveredClues 已发现的线索
 * @param conversationHistory 对话历史
 * @param gameContext 游戏上下文
 * @returns 分析结果
 */
export async function analyzeInvestigation(
  caseData: any,
  discoveredClues: any[] = [],
  conversationHistory: any[] = [],
  gameContext: any = {}
) {
  try {
    console.log('调查分析Agent开始分析案件...');
    
    // 构建分析上下文
    const analysisContext = {
      case: caseData,
      clues: discoveredClues,
      conversations: conversationHistory,
      progress: {
        timeRemaining: gameContext.timeRemaining || 180,
        conversationCount: conversationHistory.length,
        clueCount: discoveredClues.length,
        suspectInteractions: gameContext.suspectInteractions || {}
      }
    };
    
    // 构建分析请求
    const prompt = `请作为专业调查分析专家，对当前案件进行全面分析：
    
    ## 案件基本信息
    - 案件标题：${caseData.case?.title || '未知案件'}
    - 案件描述：${caseData.case?.description || '无描述'}
    - 案发地点：${caseData.case?.location || '未知'}
    - 案发时间：${caseData.case?.timeOfCrime || '未知'}
    - 受害者：${caseData.case?.victim || '未知'}
    
    ## 嫌疑人信息
    ${caseData.suspects ? caseData.suspects.map((suspect: any, index: number) => 
      `${index + 1}. ${suspect.name} - ${suspect.personality} (可疑程度: ${suspect.suspicionLevel}/10)`
    ).join('\n') : '无嫌疑人信息'}
    
    ## 已发现线索 (${discoveredClues.length}条)
    ${discoveredClues.map((clue: any, index: number) => 
      `${index + 1}. [${clue.type}] ${clue.description} (重要性: ${clue.importance}/10)`
    ).join('\n') || '暂无线索'}
    
    ## 调查进度
    - 剩余时间：${gameContext.timeRemaining || 180}秒
    - 对话轮次：${conversationHistory.length}次
    - 嫌疑人互动：${Object.keys(gameContext.suspectInteractions || {}).length}人
    
    ## 对话摘要
    ${conversationHistory.slice(-5).map((conv: any, index: number) => 
      `${index + 1}. ${conv.role === 'detective' ? '侦探' : '嫌疑人'}: ${conv.content.substring(0, 100)}...`
    ).join('\n') || '暂无对话记录'}
    
    请使用 clue-analysis 工具进行全面分析，包括：
    1. 线索关联性分析
    2. 调查进度评估
    3. 下一步建议
    4. 推理假设生成
    `;
    
    // 调用Agent
    const response = await investigationAgent.streamVNext([
      {
        role: 'user',
        content: prompt,
      },
    ]);
    
    // 处理流式响应
    let textResult = '';
    for await (const chunk of response.textStream) {
      textResult += chunk;
    }
    
    console.log('调查分析Agent响应:', textResult);
    
    // 从工具调用结果中提取数据
    const toolCalls = response.toolCalls;
    if (toolCalls && toolCalls.length > 0) {
      console.log('分析工具调用成功:', toolCalls[0]);
      return {
        success: true,
        ...toolCalls[0].result,
        agentResponse: textResult
      };
    }
    
    // 如果没有工具调用，返回基础分析
    return {
      success: true,
      analysis: textResult || '分析正在进行中...',
      suggestions: [
        '继续与嫌疑人对话收集更多信息',
        '仔细分析已有线索的关联性',
        '关注嫌疑人回答中的矛盾之处'
      ],
      progress: {
        completeness: Math.min((discoveredClues.length / 5) * 100, 100),
        confidence: Math.min((conversationHistory.length / 10) * 100, 100)
      },
      agentResponse: textResult
    };
    
  } catch (error) {
    console.error('调查分析Agent调用失败:', error);
    
    // 提供降级分析
    return {
      success: false,
      analysis: '分析系统暂时不可用，请继续收集线索。',
      suggestions: [
        '与所有嫌疑人进行对话',
        '仔细记录每个人的不在场证明',
        '寻找证言中的矛盾之处',
        '分析动机和机会'
      ],
      progress: {
        completeness: Math.min((discoveredClues.length / 5) * 100, 100),
        confidence: 50
      },
      error: error instanceof Error ? error.message : 'ANALYSIS_ERROR',
      fallback: true
    };
  }
}

/**
 * 生成推理假设
 * @param caseData 案件数据
 * @param discoveredClues 已发现的线索
 * @returns 推理假设列表
 */
export async function generateHypotheses(caseData: any, discoveredClues: any[]) {
  try {
    const hypotheses = [];
    
    // 基于嫌疑人生成假设
    if (caseData.suspects) {
      for (const suspect of caseData.suspects) {
        const hypothesis = {
          culprit: suspect.name,
          motive: generateMotive(suspect, caseData),
          opportunity: generateOpportunity(suspect, caseData),
          evidence: filterRelevantClues(discoveredClues, suspect),
          confidence: calculateConfidence(suspect, discoveredClues),
          weaknesses: identifyWeaknesses(suspect, discoveredClues)
        };
        hypotheses.push(hypothesis);
      }
    }
    
    // 按置信度排序
    hypotheses.sort((a, b) => b.confidence - a.confidence);
    
    return {
      success: true,
      hypotheses,
      recommendation: hypotheses[0],
      message: `生成了${hypotheses.length}个推理假设`
    };
    
  } catch (error) {
    console.error('推理假设生成失败:', error);
    return {
      success: false,
      hypotheses: [],
      error: error instanceof Error ? error.message : 'HYPOTHESIS_ERROR'
    };
  }
}

/**
 * 评估调查完整性
 * @param caseData 案件数据
 * @param discoveredClues 已发现的线索
 * @param conversationHistory 对话历史
 * @returns 完整性评估
 */
export function evaluateInvestigationCompleteness(
  caseData: any,
  discoveredClues: any[],
  conversationHistory: any[]
) {
  const evaluation = {
    overall: 0,
    categories: {
      evidence: 0,
      testimonies: 0,
      motives: 0,
      alibis: 0,
      relationships: 0
    },
    missing: [] as string[],
    recommendations: [] as string[]
  };
  
  // 评估证据收集
  const evidenceClues = discoveredClues.filter(clue => clue.type === 'physical');
  evaluation.categories.evidence = Math.min((evidenceClues.length / 3) * 100, 100);
  
  // 评估证言收集
  const testimonyClues = discoveredClues.filter(clue => clue.type === 'testimony');
  evaluation.categories.testimonies = Math.min((testimonyClues.length / 5) * 100, 100);
  
  // 评估动机分析
  const motiveQuestions = conversationHistory.filter(conv => 
    conv.content.includes('为什么') || conv.content.includes('动机')
  );
  evaluation.categories.motives = Math.min((motiveQuestions.length / 3) * 100, 100);
  
  // 评估不在场证明
  const alibiQuestions = conversationHistory.filter(conv => 
    conv.content.includes('在哪') || conv.content.includes('时间')
  );
  evaluation.categories.alibis = Math.min((alibiQuestions.length / 3) * 100, 100);
  
  // 评估关系分析
  const relationshipClues = discoveredClues.filter(clue => clue.type === 'circumstantial');
  evaluation.categories.relationships = Math.min((relationshipClues.length / 3) * 100, 100);
  
  // 计算总体完整性
  const categoryValues = Object.values(evaluation.categories);
  evaluation.overall = categoryValues.reduce((sum, val) => sum + val, 0) / categoryValues.length;
  
  // 识别缺失项
  if (evaluation.categories.evidence < 50) {
    evaluation.missing.push('物理证据不足');
    evaluation.recommendations.push('寻找更多现场证据');
  }
  if (evaluation.categories.testimonies < 50) {
    evaluation.missing.push('证人证言不足');
    evaluation.recommendations.push('与更多嫌疑人深入对话');
  }
  if (evaluation.categories.motives < 50) {
    evaluation.missing.push('动机分析不足');
    evaluation.recommendations.push('深入了解嫌疑人与受害者的关系');
  }
  
  return evaluation;
}

// 辅助函数
function generateMotive(suspect: any, caseData: any): string {
  const motives = [
    '经济利益冲突',
    '个人恩怨',
    '情感纠纷',
    '职业竞争',
    '家庭矛盾'
  ];
  return motives[Math.floor(Math.random() * motives.length)];
}

function generateOpportunity(suspect: any, caseData: any): string {
  return `${suspect.name}在案发时间${caseData.case?.timeOfCrime || ''}有机会接近现场`;
}

function filterRelevantClues(clues: any[], suspect: any): any[] {
  return clues.filter(clue => 
    clue.description.includes(suspect.name) || 
    clue.relatedSuspects?.includes(suspect.id)
  );
}

function calculateConfidence(suspect: any, clues: any[]): number {
  const relevantClues = filterRelevantClues(clues, suspect);
  const baseConfidence = suspect.suspicionLevel || 5;
  const clueBonus = relevantClues.length * 10;
  return Math.min(baseConfidence * 10 + clueBonus, 100);
}

function identifyWeaknesses(suspect: any, clues: any[]): string[] {
  const weaknesses = [];
  
  if (!suspect.alibi || suspect.alibi.length < 20) {
    weaknesses.push('不在场证明不充分');
  }
  
  const relevantClues = filterRelevantClues(clues, suspect);
  if (relevantClues.length < 2) {
    weaknesses.push('支持证据不足');
  }
  
  if (suspect.suspicionLevel < 7) {
    weaknesses.push('整体可疑程度较低');
  }
  
  return weaknesses;
}
